package day21.colllection;

import java.util.*;

/**
 * 集合框架功能测试类
 * 演示Java集合框架中各种集合类型的基本用法和常用操作方法
 */
public class collectiontest2 {
    
    public static void main(String[] args) {
        // 测试Collection接口的基本操作
        testCollection();
        
        // 测试List接口及其实现类
        testList();
        
        // 测试Set接口及其实现类
        testSet();
        
        // 测试Map接口及其实现类
        testMap();
        
        // 测试集合的遍历方式
        testIterator();
    }
    
    /**
     * 测试Collection接口的基本操作
     * Collection是所有集合的根接口，定义了集合的基本操作方法
     */
    public static void testCollection() {
        System.out.println("=== Collection接口基本操作测试 ===");
        
        // 创建Collection对象，使用ArrayList实现类
        Collection<String> collection = new ArrayList<>();
        
        // 添加元素
        collection.add("元素1");
        collection.add("元素2");
        collection.add("元素3");
        System.out.println("添加元素后: " + collection);
        
        // 批量添加元素
        Collection<String> moreElements = Arrays.asList("元素4", "元素5");
        collection.addAll(moreElements);
        System.out.println("批量添加元素后: " + collection);
        
        // 检查元素是否存在
        boolean contains = collection.contains("元素2");
        System.out.println("是否包含元素2: " + contains);
        
        // 检查是否包含所有指定元素
        Collection<String> checkElements = Arrays.asList("元素1", "元素3");
        boolean containsAll = collection.containsAll(checkElements);
        System.out.println("是否包含元素1和元素3: " + containsAll);
        
        // 获取集合大小
        System.out.println("集合大小: " + collection.size());
        
        // 判断集合是否为空
        System.out.println("集合是否为空: " + collection.isEmpty());
        
        // 删除指定元素
        collection.remove("元素2");
        System.out.println("删除元素2后: " + collection);
        
        // 批量删除元素
        Collection<String> removeElements = Arrays.asList("元素4", "元素5");
        collection.removeAll(removeElements);
        System.out.println("批量删除元素4和元素5后: " + collection);
        
        // 保留指定元素，删除其他元素
        Collection<String> retainElements = Arrays.asList("元素1", "元素6"); // 元素6不存在
        collection.retainAll(retainElements);
        System.out.println("保留元素1和元素6后: " + collection);
        
        // 清空集合
        collection.clear();
        System.out.println("清空集合后: " + collection);
        System.out.println("清空后集合是否为空: " + collection.isEmpty());
        System.out.println();
    }
    
    /**
     * 测试List接口及其实现类
     * List是有序集合，允许重复元素，可以通过索引访问元素
     */
    public static void testList() {
        System.out.println("=== List接口测试 ===");
        
        // ArrayList - 基于动态数组实现，查询快，增删慢
        System.out.println("--- ArrayList测试 ---");
        List<String> arrayList = new ArrayList<>();
        arrayList.add("A");
        arrayList.add("B");
        arrayList.add("C");
        arrayList.add(1, "D"); // 在指定位置插入元素
        System.out.println("ArrayList内容: " + arrayList);
        System.out.println("索引1处的元素: " + arrayList.get(1));
        System.out.println("元素A的索引: " + arrayList.indexOf("A"));
        
        // LinkedList - 基于双向链表实现，增删快，查询慢
        System.out.println("\n--- LinkedList测试 ---");
        List<String> linkedList = new LinkedList<>();
        linkedList.add("X");
        linkedList.add("Y");
        linkedList.add("Z");
        System.out.println("LinkedList内容: " + linkedList);
        
        // Vector - 线程安全的动态数组，性能较低，不推荐使用
        System.out.println("\n--- Vector测试 ---");
        List<String> vector = new Vector<>();
        vector.add("V1");
        vector.add("V2");
        System.out.println("Vector内容: " + vector);
        System.out.println();
    }
    
    /**
     * 测试Set接口及其实现类
     * Set不允许重复元素，最多包含一个null元素
     */
    public static void testSet() {
        System.out.println("=== Set接口测试 ===");
        
        // HashSet - 基于哈希表实现，元素无序，允许一个null元素
        System.out.println("--- HashSet测试 ---");
        Set<String> hashSet = new HashSet<>();
        hashSet.add("Apple");
        hashSet.add("Banana");
        hashSet.add("Orange");
        hashSet.add("Apple"); // 重复元素，不会被添加
        hashSet.add(null); // 允许null元素
        System.out.println("HashSet内容: " + hashSet);
        System.out.println("HashSet大小: " + hashSet.size());
        
        // LinkedHashSet - 基于哈希表和链表实现，保持插入顺序
        System.out.println("\n--- LinkedHashSet测试 ---");
        Set<String> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add("Dog");
        linkedHashSet.add("Cat");
        linkedHashSet.add("Bird");
        System.out.println("LinkedHashSet内容(保持插入顺序): " + linkedHashSet);
        
        // TreeSet - 基于红黑树实现，元素自然排序或自定义排序
        System.out.println("\n--- TreeSet测试 ---");
        Set<String> treeSet = new TreeSet<>();
        treeSet.add("Charlie");
        treeSet.add("Alice");
        treeSet.add("Bob");
        System.out.println("TreeSet内容(自然排序): " + treeSet);
        System.out.println();
    }
    
    /**
     * 测试Map接口及其实现类
     * Map存储键值对，键不能重复，值可以重复
     */
    public static void testMap() {
        System.out.println("=== Map接口测试 ===");
        
        // HashMap - 基于哈希表实现，允许null键和null值，无序
        System.out.println("--- HashMap测试 ---");
        Map<String, Integer> hashMap = new HashMap<>();
        hashMap.put("张三", 25);
        hashMap.put("李四", 30);
        hashMap.put("王五", 28);
        hashMap.put("张三", 26); // 相同键会覆盖原值
        hashMap.put(null, 100); // 允许null键
        hashMap.put("赵六", null); // 允许null值
        System.out.println("HashMap内容: " + hashMap);
        System.out.println("张三的年龄: " + hashMap.get("张三"));
        System.out.println("是否包含键'李四': " + hashMap.containsKey("李四"));
        System.out.println("是否包含值28: " + hashMap.containsValue(28));
        
        // LinkedHashMap - 基于哈希表和链表实现，保持插入顺序
        System.out.println("\n--- LinkedHashMap测试 ---");
        Map<String, String> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("第一", "A");
        linkedHashMap.put("第二", "B");
        linkedHashMap.put("第三", "C");
        System.out.println("LinkedHashMap内容(保持插入顺序): " + linkedHashMap);
        
        // TreeMap - 基于红黑树实现，按键排序
        System.out.println("\n--- TreeMap测试 ---");
        Map<String, Integer> treeMap = new TreeMap<>();
        treeMap.put("Charlie", 85);
        treeMap.put("Alice", 92);
        treeMap.put("Bob", 78);
        System.out.println("TreeMap内容(按键排序): " + treeMap);
        
        // Hashtable - 线程安全，不允许null键和null值，已过时
        System.out.println("\n--- Hashtable测试 ---");
        Map<String, Integer> hashtable = new Hashtable<>();
        hashtable.put("数学", 90);
        hashtable.put("英语", 85);
        hashtable.put("语文", 88);
        System.out.println("Hashtable内容: " + hashtable);
        System.out.println();
    }
    
    /**
     * 测试集合的遍历方式
     * 演示多种遍历集合的方法
     */
    public static void testIterator() {
        System.out.println("=== 集合遍历方式测试 ===");
        
        List<String> list = Arrays.asList("Java", "Python", "C++", "JavaScript");
        
        // 1. 使用增强for循环遍历
        System.out.println("--- 增强for循环遍历 ---");
        for (String item : list) {
            System.out.println(item);
        }
        
        // 2. 使用Iterator遍历
        System.out.println("\n--- Iterator遍历 ---");
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String item = iterator.next();
            System.out.println(item);
        }
        
        // 3. 使用ListIterator遍历(仅适用于List)
        System.out.println("\n--- ListIterator遍历 ---");
        ListIterator<String> listIterator = list.listIterator();
        System.out.println("正向遍历:");
        while (listIterator.hasNext()) {
            String item = listIterator.next();
            System.out.println(item);
        }
        
        System.out.println("反向遍历:");
        while (listIterator.hasPrevious()) {
            String item = listIterator.previous();
            System.out.println(item);
        }
        
        // 4. 使用forEach方法遍历(JDK 8+)
        System.out.println("\n--- forEach方法遍历 ---");
        list.forEach(System.out::println);
        
        // 5. 使用Stream API遍历(JDK 8+)
        System.out.println("\n--- Stream API遍历 ---");
        list.stream().forEach(System.out::println);
        System.out.println();
    }
}